/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package geradorImagens;

import imagemYUV.novoFormato;
import java.io.*;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import utilitarios.Conversoes;

/**
 *
 * @author Mateus
 */
public class CriarNovoFormato {

    public static byte[] imagem;
    public static File caminho;

    public static novoFormato construirFormato(File arquivo) {


        //definindo tamanho do tamanho do arquivo de entrada e convertendo o mesmo para um buffer de bytes
        imagem = new byte[(int) arquivo.length()];
        InputStream pegarBytes = null;
        try {
            pegarBytes = new FileInputStream(arquivo);
            caminho = arquivo;
        } catch (FileNotFoundException ex) {
            Logger.getLogger(CriarBmp.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            //pega o arquivo que esta na inputStream e convete para um buffer de bytes passado por parametro
            pegarBytes.read(imagem);
        } catch (IOException ex) {
            Logger.getLogger(CriarBmp.class.getName()).log(Level.SEVERE, null, ex);
        }
 
novoFormato novoformato = new novoFormato(imagem[0], imagem[1], imagem.length);

        if (novoformato.isYUV == 1) {
            if (novoformato.isCompressed == 1) {
                for (int i = 2; i < 6; i++) {
                    novoformato.altura[i - 2] = imagem[i];
                }
                for (int i = 6; i < 10; i++) {
                    novoformato.largura[i - 6] = imagem[i];
                }
                int largura = Conversoes.byteArray2Int4(novoformato.largura);
                int altura = Conversoes.byteArray2Int4(novoformato.altura);
                
                int deslocamento = 0;
                if ((largura % 4) != 0) {
                    deslocamento = (4 - ((largura * 3) % 4));
                }
                //caso correto====================================================================
                if ((altura) % 2 == 0 && (largura) % 2 == 0) {
                    MatrizYUV[] listaMatriz = new MatrizYUV[imagem.length];
                    int cont = 0;
                    int contLinha = 0;
                    for (int i = 0; i < imagem.length - 10; i += 6) {
                        
                        byte U = imagem[i + 10];
                        byte V = imagem[i + 11];
                        byte Y1 = imagem[i + 12];
                        byte Y2 = imagem[i + 13];
                        byte Y3 = imagem[i + 14];
                        byte Y4 = imagem[i + 15];
                        MatrizYUV nova = new MatrizYUV(U, V, Y1, Y2, Y3, Y4);
                        listaMatriz[cont] = nova;

                        cont++;
                    }
                    cont = 0;


                    byte[][] matrizImagem = new byte[altura][largura * 3];
                    for (int i = 0; i < altura; i += 2) {
                        for (int j = 0; j < largura * 3; j += 6) {
                            
                            byte[] v = listaMatriz[cont].linhaSuperior();
                            matrizImagem[i][j] = v[0];
                            matrizImagem[i][j + 1] = v[1];
                            matrizImagem[i][j + 2] = v[2];
                            matrizImagem[i][j + 3] = v[3];
                            matrizImagem[i][j + 4] = v[4];
                            matrizImagem[i][j + 5] = v[5];

                            byte[] v1 = listaMatriz[cont].linhaInferior();
                            matrizImagem[i + 1][j] = v1[0];
                            matrizImagem[i + 1][j + 1] = v1[1];
                            matrizImagem[i + 1][j + 2] = v1[2];
                            matrizImagem[i + 1][j + 3] = v1[3];
                            matrizImagem[i + 1][j + 4] = v1[4];
                            matrizImagem[i + 1][j + 5] = v1[5];
                            cont++;
                        }
                    }
                    cont = 0;
                    for (int i = 0; i < altura; i++) {
                        for (int j = 0; j < largura * 3; j++) {
                            novoformato.imagem[cont] = matrizImagem[i][j];
                            cont++;
                        }
                    }
                }
                //caso em que a linha sobra==================================================================================
                if((altura) % 2 != 0 && (largura) % 2 == 0){
                    MatrizYUV[] listaMatriz = new MatrizYUV[imagem.length];
                    int cont = 0;
                    int linha = 0;
                    int coluna = 0;
                    boolean ultimaLinha = false;
                    
                    for(int i = 0; i < imagem.length-10; i+=6){
                        
                        if(linha == (largura*3))
                            coluna+=2;
                        
                        if(coluna == (altura -1)){
                            ultimaLinha = true;
                            for(int j = i; j < imagem.length-10; j += 4){
                                byte U = imagem[j + 10];
                                byte V = imagem[j + 11];
                                byte Y1 = imagem[j + 12];
                                byte Y2 = imagem[j + 13];
                                byte Y3 = 'F';
                                byte Y4 = 'F';
                                MatrizYUV nova = new MatrizYUV(U, V, Y1, Y2, Y3, Y4);
                                listaMatriz[cont] = nova;
                                cont++;                                
                            }
                            i = imagem.length - 10;
                        }
                        if(ultimaLinha == false){
                            byte U = imagem[i + 10];
                            byte V = imagem[i + 11];
                            byte Y1 = imagem[i + 12];
                            byte Y2 = imagem[i + 13];
                            byte Y3 = imagem[i + 14];
                            byte Y4 = imagem[i + 15];
                            MatrizYUV nova = new MatrizYUV(U, V, Y1, Y2, Y3, Y4);
                            listaMatriz[cont] = nova;
                            cont++;
                            linha += 6;
                        }
                    }
                    
                    cont = 0;
                    ultimaLinha = false;
                    boolean ultimaColuna = false;
                    byte[][] matrizImagem = new byte[altura][largura * 3];
                    for (int i = 0; i < altura; i += 2) {
                        ultimaColuna = false;
                        for (int j = 0; j < largura * 3; j += 6) {

                            if(i == altura-1){
                                ultimaLinha = true;
                                for (int a = 0; a < largura * 3; a += 6){
                                    
                                    byte[] v0 = listaMatriz[cont].linhaSuperior();
                                    matrizImagem[i][a] = v0[0];
                                    matrizImagem[i][a + 1] = v0[1];
                                    matrizImagem[i][a + 2] = v0[2];
                                    matrizImagem[i][a + 3] = v0[3];
                                    matrizImagem[i][a + 4] = v0[4];
                                    matrizImagem[i][a + 5] = v0[5];
                                    cont++;
                                }
                                j = (largura*3);
                            }
                            if(ultimaLinha == false){
                                byte[] v0 = listaMatriz[cont].linhaSuperior();
                                matrizImagem[i][j] = v0[0];
                                matrizImagem[i][j + 1] = v0[1];
                                matrizImagem[i][j + 2] = v0[2];
                                matrizImagem[i][j + 3] = v0[3];
                                matrizImagem[i][j + 4] = v0[4];
                                matrizImagem[i][j + 5] = v0[5];

                                byte[] v1 = listaMatriz[cont].linhaInferior();
                                matrizImagem[i + 1][j] = v1[0];
                                matrizImagem[i + 1][j + 1] = v1[1];
                                matrizImagem[i + 1][j + 2] = v1[2];
                                matrizImagem[i + 1][j + 3] = v1[3];
                                matrizImagem[i + 1][j + 4] = v1[4];
                                matrizImagem[i + 1][j + 5] = v1[5];
                                cont++;
                            }
                        }
                    }
                    cont = 0;
                    for (int i = 0; i < altura; i++) {
                        for (int j = 0; j < largura * 3; j++) {
                            novoformato.imagem[cont] = matrizImagem[i][j];
                            cont++;
                        }
                    }
                }
                
                //caso em que a coluna sobra=======================================================================================
                if((altura) % 2 == 0 && (largura) % 2 != 0){
                    MatrizYUV[] listaMatriz = new MatrizYUV[imagem.length];
                    int cont = 0;
                    int linha = 0;
                    int coluna = 0;
                    boolean ultimaLinha = false;
                    
                    for(int i = 0; i < imagem.length-10; i+=6){
                        boolean verefica = false;
                        if (linha == ((largura * 3) - 3)) {
                            byte U = imagem[i + 10];
                            byte V = imagem[i + 11];
                            byte Y1 = imagem[i + 12];
                            byte Y2 = 'F';
                            byte Y3 = imagem[i + 13];
                            byte Y4 = 'F';
                            MatrizYUV nova = new MatrizYUV(U, V, Y1, Y2, Y3, Y4);
                            listaMatriz[cont] = nova;
                            cont++;
                            linha = 0;
                            verefica = true;
                            coluna+=2;
                            i -= 2;
                        }
                        
                        if(verefica == false){
                            byte U = imagem[i + 10];
                            byte V = imagem[i + 11];
                            byte Y1 = imagem[i + 12];
                            byte Y2 = imagem[i + 13];
                            byte Y3 = imagem[i + 14];
                            byte Y4 = imagem[i + 15];
                            MatrizYUV nova = new MatrizYUV(U, V, Y1, Y2, Y3, Y4);
                            listaMatriz[cont] = nova;
                            cont++;
                            linha += 6;
                        }
                    }
                    
                    cont = 0;
                    ultimaLinha = false;
                    boolean ultimaColuna = false;
                    byte[][] matrizImagem = new byte[altura][largura * 3];
                    for (int i = 0; i < altura; i += 2) {
                        ultimaColuna = false;
                        for (int j = 0; j < largura * 3; j += 6) {

                            if((j == (largura*3)-3)){
                                byte[] v0 = listaMatriz[cont].linhaSuperior();
                                matrizImagem[i][j] = v0[0];
                                matrizImagem[i][j + 1] = v0[1];
                                matrizImagem[i][j + 2] = v0[2];

                                byte[] v1 = listaMatriz[cont].linhaInferior();
                                matrizImagem[i + 1][j] = v1[0];
                                matrizImagem[i + 1][j + 1] = v1[1];
                                matrizImagem[i + 1][j + 2] = v1[2];
                                cont++;
                                j += 3;
                                ultimaColuna = true;                               
                            }
                            
                            if(ultimaColuna == false){
                                byte[] v0 = listaMatriz[cont].linhaSuperior();
                                matrizImagem[i][j] = v0[0];
                                matrizImagem[i][j + 1] = v0[1];
                                matrizImagem[i][j + 2] = v0[2];
                                matrizImagem[i][j + 3] = v0[3];
                                matrizImagem[i][j + 4] = v0[4];
                                matrizImagem[i][j + 5] = v0[5];

                                byte[] v1 = listaMatriz[cont].linhaInferior();
                                matrizImagem[i + 1][j] = v1[0];
                                matrizImagem[i + 1][j + 1] = v1[1];
                                matrizImagem[i + 1][j + 2] = v1[2];
                                matrizImagem[i + 1][j + 3] = v1[3];
                                matrizImagem[i + 1][j + 4] = v1[4];
                                matrizImagem[i + 1][j + 5] = v1[5];
                                cont++;
                            }
                        }
                    }
                    cont = 0;
                    for (int i = 0; i < altura; i++) {
                        for (int j = 0; j < largura * 3; j++) {
                            novoformato.imagem[cont] = matrizImagem[i][j];
                            cont++;
                        }
                    }
                }
                
                //caso mais chato linha e coluna bugada =====================================================================
                if ((altura) % 2 != 0 && (largura) % 2 != 0) {
                    MatrizYUV[] listaMatriz = new MatrizYUV[imagem.length];
                    int cont = 0;
                    int linha = 0;
                    int coluna = 0;
                    boolean ultimaLinha = false;
                    
                    for(int i = 0; i < imagem.length-10; i+=6){
                        boolean verefica = false;
                        if ((linha == (largura * 3) - 3) && ultimaLinha == false) {
                            byte U = imagem[i + 10];
                            byte V = imagem[i + 11];
                            byte Y1 = imagem[i + 12];
                            byte Y2 = 'F';
                            byte Y3 = imagem[i + 13];
                            byte Y4 = 'F';
                            MatrizYUV nova = new MatrizYUV(U, V, Y1, Y2, Y3, Y4);
                            listaMatriz[cont] = nova;
                            cont++;
                            linha = 0;
                            verefica = true;
                            coluna+=2;
                            i -= 2;
                        }
                        
                        if(coluna == (altura -1) && verefica == false){
                            ultimaLinha = true;
                            for(int j = i; j < imagem.length-10; j += 4){
                                byte U = imagem[j + 10];
                                byte V = imagem[j + 11];
                                byte Y1 = imagem[j + 12];
                                byte Y2 = imagem[j + 13];
                                byte Y3 = 'F';
                                byte Y4 = 'F';
                                MatrizYUV nova = new MatrizYUV(U, V, Y1, Y2, Y3, Y4);
                                listaMatriz[cont] = nova;
                                cont++;                                
                                //caso especial
                                if(j + 8 == imagem.length-10){
                                    j += 4;
                                    U = imagem[j + 10];
                                    V = imagem[j + 11];
                                    Y1 = imagem[j + 12];
                                    Y2 = 'F';
                                    Y3 = 'F';
                                    Y4 = 'F';
                                    nova = new MatrizYUV(U, V, Y1, Y2, Y3, Y4);
                                    listaMatriz[cont] = nova;
                                    cont++;
                                    i = imagem.length -10;
                                    break;
                                }
                            }
                        }
                        if(ultimaLinha == false && (verefica == false)){
                            byte U = imagem[i + 10];
                            byte V = imagem[i + 11];
                            byte Y1 = imagem[i + 12];
                            byte Y2 = imagem[i + 13];
                            byte Y3 = imagem[i + 14];
                            byte Y4 = imagem[i + 15];
                            MatrizYUV nova = new MatrizYUV(U, V, Y1, Y2, Y3, Y4);
                            listaMatriz[cont] = nova;
                            cont++;
                            linha += 6;
                        }
                    }
                    
                    //transformar matrizes em imagens
                     cont = 0;
                    ultimaLinha = false;
                    boolean ultimaColuna = false;
                    byte[][] matrizImagem = new byte[altura][largura * 3];
                    for (int i = 0; i < altura; i += 2) {
                        ultimaColuna = false;
                        for (int j = 0; j < largura * 3; j += 6) {

                            if((j == (largura*3)-3) && (ultimaLinha == false)){
                                byte[] v0 = listaMatriz[cont].linhaSuperior();
                                matrizImagem[i][j] = v0[0];
                                matrizImagem[i][j + 1] = v0[1];
                                matrizImagem[i][j + 2] = v0[2];

                                byte[] v1 = listaMatriz[cont].linhaInferior();
                                matrizImagem[i + 1][j] = v1[0];
                                matrizImagem[i + 1][j + 1] = v1[1];
                                matrizImagem[i + 1][j + 2] = v1[2];
                                cont++;
                                j += 3;
                                ultimaColuna = true;                               
                            }
                            if(i == altura-1){
                                ultimaLinha = true;
                                for (int a = 0; a < largura * 3; a += 6){
                                    
                                     if(a == (largura*3)-3){
                                        byte[] v0 = listaMatriz[cont].linhaSuperior();
                                        matrizImagem[i][a] = v0[0];
                                        matrizImagem[i][a + 1] = v0[1];
                                        matrizImagem[i][a + 2] = v0[2];
                                        j = largura*3;
                                        break;
                                    }
                                    
                                    byte[] v0 = listaMatriz[cont].linhaSuperior();
                                    matrizImagem[i][a] = v0[0];
                                    matrizImagem[i][a + 1] = v0[1];
                                    matrizImagem[i][a + 2] = v0[2];
                                    matrizImagem[i][a + 3] = v0[3];
                                    matrizImagem[i][a + 4] = v0[4];
                                    matrizImagem[i][a + 5] = v0[5];
                                    cont++;
                                }
                            }
                            if(ultimaLinha == false && ultimaColuna == false){
                                byte[] v0 = listaMatriz[cont].linhaSuperior();
                                matrizImagem[i][j] = v0[0];
                                matrizImagem[i][j + 1] = v0[1];
                                matrizImagem[i][j + 2] = v0[2];
                                matrizImagem[i][j + 3] = v0[3];
                                matrizImagem[i][j + 4] = v0[4];
                                matrizImagem[i][j + 5] = v0[5];

                                byte[] v1 = listaMatriz[cont].linhaInferior();
                                matrizImagem[i + 1][j] = v1[0];
                                matrizImagem[i + 1][j + 1] = v1[1];
                                matrizImagem[i + 1][j + 2] = v1[2];
                                matrizImagem[i + 1][j + 3] = v1[3];
                                matrizImagem[i + 1][j + 4] = v1[4];
                                matrizImagem[i + 1][j + 5] = v1[5];
                                cont++;
                            }
                        }
                    }
                    cont = 0;
                    for (int i = 0; i < altura; i++) {
                        for (int j = 0; j < largura * 3; j++) {
                            novoformato.imagem[cont] = matrizImagem[i][j];
                            cont++;
                        }
                    }
                }
            }
        }
                
        return novoformato;
    }

    public static novoFormato reconstruirImagem(byte[] imagem) {

        novoFormato novoformato = new novoFormato(imagem[0], imagem[1], imagem.length);

        if (novoformato.isYUV == 1) {
            if (novoformato.isCompressed == 1) {
                for (int i = 2; i < 6; i++) {
                    novoformato.altura[i - 2] = imagem[i];
                }
                for (int i = 6; i < 10; i++) {
                    novoformato.largura[i - 6] = imagem[i];
                }
                int largura = Conversoes.byteArray2Int4(novoformato.largura);
                int altura = Conversoes.byteArray2Int4(novoformato.altura);
               
                int deslocamento = 0;
                if ((largura % 4) != 0) {
                    deslocamento = (4 - ((largura * 3) % 4));
                }
                //caso correto====================================================================
                if ((altura) % 2 == 0 && (largura) % 2 == 0) {
                    MatrizYUV[] listaMatriz = new MatrizYUV[imagem.length];
                    int cont = 0;
                    int contLinha = 0;
                    for (int i = 0; i < imagem.length - 10; i += 6) {
                        
                        byte U = imagem[i + 10];
                        byte V = imagem[i + 11];
                        byte Y1 = imagem[i + 12];
                        byte Y2 = imagem[i + 13];
                        byte Y3 = imagem[i + 14];
                        byte Y4 = imagem[i + 15];
                        MatrizYUV nova = new MatrizYUV(U, V, Y1, Y2, Y3, Y4);
                        listaMatriz[cont] = nova;

                        cont++;
                        
                    }
                    cont = 0;


                    byte[][] matrizImagem = new byte[altura][largura * 3];
                    for (int i = 0; i < altura; i += 2) {
                        for (int j = 0; j < largura * 3; j += 6) {
                            
                            byte[] v = listaMatriz[cont].linhaSuperior();
                            matrizImagem[i][j] = v[0];
                            matrizImagem[i][j + 1] = v[1];
                            matrizImagem[i][j + 2] = v[2];
                            matrizImagem[i][j + 3] = v[3];
                            matrizImagem[i][j + 4] = v[4];
                            matrizImagem[i][j + 5] = v[5];

                            byte[] v1 = listaMatriz[cont].linhaInferior();
                            matrizImagem[i + 1][j] = v1[0];
                            matrizImagem[i + 1][j + 1] = v1[1];
                            matrizImagem[i + 1][j + 2] = v1[2];
                            matrizImagem[i + 1][j + 3] = v1[3];
                            matrizImagem[i + 1][j + 4] = v1[4];
                            matrizImagem[i + 1][j + 5] = v1[5];
                            cont++;
                        }
                    }
                    cont = 0;
                    for (int i = 0; i < altura; i++) {
                        for (int j = 0; j < largura * 3; j++) {
                            novoformato.imagem[cont] = matrizImagem[i][j];
                            cont++;
                        }
                    }
                }
                //caso em que a linha sobra==================================================================================
                if((altura) % 2 != 0 && (largura) % 2 == 0){
                    MatrizYUV[] listaMatriz = new MatrizYUV[imagem.length];
                    int cont = 0;
                    int linha = 0;
                    int coluna = 0;
                    boolean ultimaLinha = false;
                    
                    for(int i = 0; i < imagem.length-10; i+=6){
                        
                        if(linha == (largura*3))
                            coluna+=2;
                        
                        if(coluna == (altura -1)){
                            ultimaLinha = true;
                            for(int j = i; j < imagem.length-10; j += 4){
                                byte U = imagem[j + 10];
                                byte V = imagem[j + 11];
                                byte Y1 = imagem[j + 12];
                                byte Y2 = imagem[j + 13];
                                byte Y3 = 'F';
                                byte Y4 = 'F';
                                MatrizYUV nova = new MatrizYUV(U, V, Y1, Y2, Y3, Y4);
                                listaMatriz[cont] = nova;
                                cont++;                                
                            }
                            i = imagem.length - 10;
                        }
                        if(ultimaLinha == false){
                            byte U = imagem[i + 10];
                            byte V = imagem[i + 11];
                            byte Y1 = imagem[i + 12];
                            byte Y2 = imagem[i + 13];
                            byte Y3 = imagem[i + 14];
                            byte Y4 = imagem[i + 15];
                            MatrizYUV nova = new MatrizYUV(U, V, Y1, Y2, Y3, Y4);
                            listaMatriz[cont] = nova;
                            cont++;
                            linha += 6;
                        }
                    }
                    
                    cont = 0;
                    ultimaLinha = false;
                    boolean ultimaColuna = false;
                    byte[][] matrizImagem = new byte[altura][largura * 3];
                    for (int i = 0; i < altura; i += 2) {
                        ultimaColuna = false;
                        for (int j = 0; j < largura * 3; j += 6) {

                            if(i == altura-1){
                                ultimaLinha = true;
                                for (int a = 0; a < largura * 3; a += 6){
                                    
                                    byte[] v0 = listaMatriz[cont].linhaSuperior();
                                    matrizImagem[i][a] = v0[0];
                                    matrizImagem[i][a + 1] = v0[1];
                                    matrizImagem[i][a + 2] = v0[2];
                                    matrizImagem[i][a + 3] = v0[3];
                                    matrizImagem[i][a + 4] = v0[4];
                                    matrizImagem[i][a + 5] = v0[5];
                                    cont++;
                                }
                                j = (largura*3);
                            }
                            if(ultimaLinha == false){
                                byte[] v0 = listaMatriz[cont].linhaSuperior();
                                matrizImagem[i][j] = v0[0];
                                matrizImagem[i][j + 1] = v0[1];
                                matrizImagem[i][j + 2] = v0[2];
                                matrizImagem[i][j + 3] = v0[3];
                                matrizImagem[i][j + 4] = v0[4];
                                matrizImagem[i][j + 5] = v0[5];

                                byte[] v1 = listaMatriz[cont].linhaInferior();
                                matrizImagem[i + 1][j] = v1[0];
                                matrizImagem[i + 1][j + 1] = v1[1];
                                matrizImagem[i + 1][j + 2] = v1[2];
                                matrizImagem[i + 1][j + 3] = v1[3];
                                matrizImagem[i + 1][j + 4] = v1[4];
                                matrizImagem[i + 1][j + 5] = v1[5];
                                cont++;
                            }
                        }
                    }
                    cont = 0;
                    for (int i = 0; i < altura; i++) {
                        for (int j = 0; j < largura * 3; j++) {
                            novoformato.imagem[cont] = matrizImagem[i][j];
                            cont++;
                        }
                    }
                }
                
                //caso em que a coluna sobra=======================================================================================
                if((altura) % 2 == 0 && (largura) % 2 != 0){
                    MatrizYUV[] listaMatriz = new MatrizYUV[imagem.length];
                    int cont = 0;
                    int linha = 0;
                    int coluna = 0;
                    boolean ultimaLinha = false;
                    
                    for(int i = 0; i < imagem.length-10; i+=6){
                        boolean verefica = false;
                        if (linha == ((largura * 3) - 3)) {
                            byte U = imagem[i + 10];
                            byte V = imagem[i + 11];
                            byte Y1 = imagem[i + 12];
                            byte Y2 = 'F';
                            byte Y3 = imagem[i + 13];
                            byte Y4 = 'F';
                            MatrizYUV nova = new MatrizYUV(U, V, Y1, Y2, Y3, Y4);
                            listaMatriz[cont] = nova;
                            cont++;
                            linha = 0;
                            verefica = true;
                            coluna+=2;
                            i -= 2;
                        }
                        
                        if(verefica == false){
                            byte U = imagem[i + 10];
                            byte V = imagem[i + 11];
                            byte Y1 = imagem[i + 12];
                            byte Y2 = imagem[i + 13];
                            byte Y3 = imagem[i + 14];
                            byte Y4 = imagem[i + 15];
                            MatrizYUV nova = new MatrizYUV(U, V, Y1, Y2, Y3, Y4);
                            listaMatriz[cont] = nova;
                            cont++;
                            linha += 6;
                        }
                    }
                    
                    cont = 0;
                    ultimaLinha = false;
                    boolean ultimaColuna = false;
                    byte[][] matrizImagem = new byte[altura][largura * 3];
                    for (int i = 0; i < altura; i += 2) {
                        ultimaColuna = false;
                        for (int j = 0; j < largura * 3; j += 6) {

                            if((j == (largura*3)-3)){
                                byte[] v0 = listaMatriz[cont].linhaSuperior();
                                matrizImagem[i][j] = v0[0];
                                matrizImagem[i][j + 1] = v0[1];
                                matrizImagem[i][j + 2] = v0[2];

                                byte[] v1 = listaMatriz[cont].linhaInferior();
                                matrizImagem[i + 1][j] = v1[0];
                                matrizImagem[i + 1][j + 1] = v1[1];
                                matrizImagem[i + 1][j + 2] = v1[2];
                                cont++;
                                j += 3;
                                ultimaColuna = true;                               
                            }
                            
                            if(ultimaColuna == false){
                                byte[] v0 = listaMatriz[cont].linhaSuperior();
                                matrizImagem[i][j] = v0[0];
                                matrizImagem[i][j + 1] = v0[1];
                                matrizImagem[i][j + 2] = v0[2];
                                matrizImagem[i][j + 3] = v0[3];
                                matrizImagem[i][j + 4] = v0[4];
                                matrizImagem[i][j + 5] = v0[5];

                                byte[] v1 = listaMatriz[cont].linhaInferior();
                                matrizImagem[i + 1][j] = v1[0];
                                matrizImagem[i + 1][j + 1] = v1[1];
                                matrizImagem[i + 1][j + 2] = v1[2];
                                matrizImagem[i + 1][j + 3] = v1[3];
                                matrizImagem[i + 1][j + 4] = v1[4];
                                matrizImagem[i + 1][j + 5] = v1[5];
                                cont++;
                            }
                        }
                    }
                    cont = 0;
                    for (int i = 0; i < altura; i++) {
                        for (int j = 0; j < largura * 3; j++) {
                            novoformato.imagem[cont] = matrizImagem[i][j];
                            cont++;
                        }
                    }
                }
                
                //caso mais chato linha e coluna bugada =====================================================================
                if ((altura) % 2 != 0 && (largura) % 2 != 0) {
                    MatrizYUV[] listaMatriz = new MatrizYUV[imagem.length];
                    int cont = 0;
                    int linha = 0;
                    int coluna = 0;
                    boolean ultimaLinha = false;
                    
                    for(int i = 0; i < imagem.length-10; i+=6){
                        boolean verefica = false;
                        if ((linha == (largura * 3) - 3) && ultimaLinha == false) {
                            byte U = imagem[i + 10];
                            byte V = imagem[i + 11];
                            byte Y1 = imagem[i + 12];
                            byte Y2 = 'F';
                            byte Y3 = imagem[i + 13];
                            byte Y4 = 'F';
                            MatrizYUV nova = new MatrizYUV(U, V, Y1, Y2, Y3, Y4);
                            listaMatriz[cont] = nova;
                            cont++;
                            linha = 0;
                            verefica = true;
                            coluna+=2;
                            i -= 2;
                        }
                        
                        if(coluna == (altura -1) && verefica == false){
                            ultimaLinha = true;
                            for(int j = i; j < imagem.length-10; j += 4){
                                byte U = imagem[j + 10];
                                byte V = imagem[j + 11];
                                byte Y1 = imagem[j + 12];
                                byte Y2 = imagem[j + 13];
                                byte Y3 = 'F';
                                byte Y4 = 'F';
                                MatrizYUV nova = new MatrizYUV(U, V, Y1, Y2, Y3, Y4);
                                listaMatriz[cont] = nova;
                                cont++;                                
                                //caso especial
                                if(j + 8 == imagem.length-10){
                                    j += 4;
                                    U = imagem[j + 10];
                                    V = imagem[j + 11];
                                    Y1 = imagem[j + 12];
                                    Y2 = 'F';
                                    Y3 = 'F';
                                    Y4 = 'F';
                                    nova = new MatrizYUV(U, V, Y1, Y2, Y3, Y4);
                                    listaMatriz[cont] = nova;
                                    cont++;
                                    i = imagem.length -10;
                                    break;
                                }
                            }
                        }
                        if(ultimaLinha == false && (verefica == false)){
                            byte U = imagem[i + 10];
                            byte V = imagem[i + 11];
                            byte Y1 = imagem[i + 12];
                            byte Y2 = imagem[i + 13];
                            byte Y3 = imagem[i + 14];
                            byte Y4 = imagem[i + 15];
                            MatrizYUV nova = new MatrizYUV(U, V, Y1, Y2, Y3, Y4);
                            listaMatriz[cont] = nova;
                            cont++;
                            linha += 6;
                        }
                    }
                    
                    //transformar matrizes em imagens
                     cont = 0;
                    ultimaLinha = false;
                    boolean ultimaColuna = false;
                    byte[][] matrizImagem = new byte[altura][largura * 3];
                    for (int i = 0; i < altura; i += 2) {
                        ultimaColuna = false;
                        for (int j = 0; j < largura * 3; j += 6) {

                            if((j == (largura*3)-3) && (ultimaLinha == false)){
                                byte[] v0 = listaMatriz[cont].linhaSuperior();
                                matrizImagem[i][j] = v0[0];
                                matrizImagem[i][j + 1] = v0[1];
                                matrizImagem[i][j + 2] = v0[2];

                                byte[] v1 = listaMatriz[cont].linhaInferior();
                                matrizImagem[i + 1][j] = v1[0];
                                matrizImagem[i + 1][j + 1] = v1[1];
                                matrizImagem[i + 1][j + 2] = v1[2];
                                cont++;
                                j += 3;
                                ultimaColuna = true;                               
                            }
                            if(i == altura-1){
                                ultimaLinha = true;
                                for (int a = 0; a < largura * 3; a += 6){
                                    
                                     if(a == (largura*3)-3){
                                        byte[] v0 = listaMatriz[cont].linhaSuperior();
                                        matrizImagem[i][a] = v0[0];
                                        matrizImagem[i][a + 1] = v0[1];
                                        matrizImagem[i][a + 2] = v0[2];
                                        j = largura*3;
                                        break;
                                    }
                                    
                                    byte[] v0 = listaMatriz[cont].linhaSuperior();
                                    matrizImagem[i][a] = v0[0];
                                    matrizImagem[i][a + 1] = v0[1];
                                    matrizImagem[i][a + 2] = v0[2];
                                    matrizImagem[i][a + 3] = v0[3];
                                    matrizImagem[i][a + 4] = v0[4];
                                    matrizImagem[i][a + 5] = v0[5];
                                    cont++;
                                }
                            }
                            if(ultimaLinha == false && ultimaColuna == false){
                                byte[] v0 = listaMatriz[cont].linhaSuperior();
                                matrizImagem[i][j] = v0[0];
                                matrizImagem[i][j + 1] = v0[1];
                                matrizImagem[i][j + 2] = v0[2];
                                matrizImagem[i][j + 3] = v0[3];
                                matrizImagem[i][j + 4] = v0[4];
                                matrizImagem[i][j + 5] = v0[5];

                                byte[] v1 = listaMatriz[cont].linhaInferior();
                                matrizImagem[i + 1][j] = v1[0];
                                matrizImagem[i + 1][j + 1] = v1[1];
                                matrizImagem[i + 1][j + 2] = v1[2];
                                matrizImagem[i + 1][j + 3] = v1[3];
                                matrizImagem[i + 1][j + 4] = v1[4];
                                matrizImagem[i + 1][j + 5] = v1[5];
                                cont++;
                            }
                        }
                    }
                    cont = 0;
                    for (int i = 0; i < altura; i++) {
                        for (int j = 0; j < largura * 3; j++) {
                            novoformato.imagem[cont] = matrizImagem[i][j];
                            cont++;
                        }
                    }
                }
            }
        }
                
        return novoformato;
    }
}
